package com.hcj.springcloud.BridgePattern;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

/**
 * 【重点】桥接模式-demo
 * 当我们需要将抽象与其实现分离时，使用Bridge，以便两者可以独立变化。
 * 这种类型的设计模式属于结构模式，因为这种模式通过在它们之间提供桥接结构来分离实现类和抽象类。
 * 这种模式涉及一个接口，它充当一个桥梁，使具体类的功能独立于接口实现者类。两种类型的类都可以在结构上进行更改而不会相互影响。
 *
 * @author huangchangjin
 * @date 2023/11/27 15:23
 */
@Slf4j
public class Demo {
    interface DrawAPI {
        void drawCircle(int radius, int x, int y);
    }

    static class RedCircle implements DrawAPI {

        @Override
        public void drawCircle(int radius, int x, int y) {
            log.info("画-红-色圈 radius = {}, x = {}, y = {}", radius, x, y);
        }
    }

    static class GreenCircle implements DrawAPI {

        @Override
        public void drawCircle(int radius, int x, int y) {
            log.info("画-绿-色圈 radius = {}, x = {}, y = {}", radius, x, y);
        }
    }

    static abstract class Shape {
        protected DrawAPI drawAPI;

        public Shape(DrawAPI drawAPI) {
            this.drawAPI = drawAPI;
        }

        abstract void draw();
    }

    static class Circle extends Shape {

        private Integer radius;
        private Integer x;
        private Integer y;

        public Circle(DrawAPI drawAPI, Integer radius, Integer x, Integer y) {
            super(drawAPI);
            this.x = x;
            this.y = y;
            this.radius = radius;
        }

        @Override
        void draw() {
            drawAPI.drawCircle(x, y, radius);
        }
    }

    @Test
    public void test_main() {
        // 抽象和实现可以互不干扰
        Shape shapeOfRed = new Circle(new RedCircle(), 1, 1, 1);
        shapeOfRed.draw();
        Shape shapeOfGreen = new Circle(new GreenCircle(), 1, 1, 1);
        shapeOfGreen.draw();
    }
}
